//******************************************************************
//******************************************************************
//**********          ANts Peer To Peer Sources        *************
//
// ANts P2P realizes a third generation P2P net. It protects your
// privacy while you are connected and makes you not trackable, hiding
// your identity (ip) and crypting everything you are sending/receiving
// from others.

// Copyright (C) 2004  Roberto Rossi

// This program is free software; you can redistribute it and/or
// modify it under the terms of the GNU General Public License
// as published by the Free Software Foundation; either version 2
// of the License, or (at your option) any later version.

// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
// GNU General Public License for more details.

// You should have received a copy of the GNU General Public License
// along with this program; if not, write to the Free Software
// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.

package ants.p2p.irc;

import java.net.*;
import java.util.*;
import java.awt.*;
import javax.swing.*;
import javax.swing.text.*;
import java.io.*;

import ants.p2p.gui.*;
import ants.p2p.*;
import ants.p2p.filesharing.*;

import org.jibble.pircbot.*;
import org.apache.log4j.*;

public class IrcBot extends PircBot {
    ConnectionAntPanel caller;
    ChatAntPanel chatPanel;
    Hashtable channels = new Hashtable();
    Hashtable topics = new Hashtable();

    public static final String connectionStateChannel = ji.JI.i("Connection state");

    boolean banWhoisResult = false;
    String banFromChannel = null;

    int channelCounter = 0;

    boolean inibitAutoreconnect = false;

    static Logger _logger = Logger.getLogger(IrcBot.class.getName());

    public IrcBot(String nick, ConnectionAntPanel caller) {
        this.setName(nick);
        this.caller = caller;
    }

    public void shutdown(){
      synchronized(this){
        this.inibitAutoreconnect = true;
        this.disconnect();
      }
    }

    public void removeDiscussion(String key){
      if(key != null && key.length() > 0 && key.charAt(0) == '#')
        key = key.toLowerCase();
      this.channels.remove(key);
      this.topics.remove(key);
    }

    void createDiscussion(String key){
      if(key != null && key.length() > 0 && key.charAt(0) == '#')
        key = key.toLowerCase();
      StyledDocument discussion = new StyledDiscussion();
      try{
        discussion.insertString(0, "", null);
      }catch(Exception e){_logger.error("",e);}
      this.channels.put(key,discussion);
      this.chatPanel.addDiscussion(key);
    }

    void createTopic(String key, String topic){
      if(key != null && key.length() > 0 && key.charAt(0) == '#'){
        key = key.toLowerCase();
        this.topics.put(key, topic);
      }
    }

    public StyledDocument getDiscussion(String key){
      if(key != null && key.length() > 0 && key.charAt(0) == '#')
        key = key.toLowerCase();
      return (StyledDocument)this.channels.get(key);
    }

    public Object[] getDiscussions(){
      Enumeration keys = this.channels.keys();
      ArrayList discussions = new ArrayList();
      while(keys.hasMoreElements())
        discussions.add(keys.nextElement());
      Collections.sort(discussions);
      if(discussions.remove(IrcBot.connectionStateChannel)){
        discussions.add(0,IrcBot.connectionStateChannel);
      }
      return discussions.toArray();
    }

    public String getTopic(String key){
      if(key != null && key.length() > 0 && key.charAt(0) == '#')
        key = key.toLowerCase();

      String topic = (String)this.topics.get(key);
      if(topic != null)
        return (String)this.topics.get(key);
      else
        return "";
    }

    public void setMessage(String key, String message, String sender) {
      if(key != null && key.length() > 0 && key.charAt(0) == '#')
        key = key.toLowerCase();
      if(this.channels.get(key)==null){
        this.createDiscussion(key);
      }
      StyledDocument discussion = (StyledDocument)this.channels.get(key);
      try{
        AttributeSet styles = null;
        if(sender.equals(this.getNick()))
          styles = discussion.getStyle("blue");
        else
          styles = discussion.getStyle("red");
        discussion.insertString(discussion.getLength(),"\n" + sender + " ", styles);
        String insertionDate = (new Date()).toLocaleString();
        String insertionTime = insertionDate.substring(insertionDate.indexOf(' ')+1, insertionDate.length());
        discussion.insertString(discussion.getLength(),insertionTime + ": ", discussion.getStyle("gray"));
        StringTokenizer lxr = new StringTokenizer(message);
        while(lxr.hasMoreTokens()){
          discussion.insertString(discussion.getLength(),
                                  " " + lxr.nextToken(), discussion.getStyle("regular"));
        }
      }catch(Exception e){_logger.error("",e);}
      this.channels.put(key, discussion);
    }

    public void setControlMessage(String key, String message) {
      if(key != null && key.length() > 0 && key.charAt(0) == '#')
        key = key.toLowerCase();
      if(this.channels.get(key)==null){
        this.createDiscussion(key);
      }
      StyledDocument discussion = (StyledDocument)this.channels.get(key);
      try{
        AttributeSet styles = null;
        styles = discussion.getStyle("green");
        discussion.insertString(discussion.getLength(),"\n", styles);
        String insertionDate = (new Date()).toLocaleString();
        String insertionTime = insertionDate.substring(insertionDate.indexOf(' ')+1, insertionDate.length());
        discussion.insertString(discussion.getLength(),insertionTime + ": ", discussion.getStyle("gray"));
        StringTokenizer lxr = new StringTokenizer(message);
        while(lxr.hasMoreTokens()){
          discussion.insertString(discussion.getLength(),
                                  " " + lxr.nextToken(), discussion.getStyle("green"));
        }
      }catch(Exception e){_logger.error("",e);}
      this.channels.put(key, discussion);
    }

    public void setStyledControlMessage(String key, String message, String style) {
      if(key != null && key.length() > 0 && key.charAt(0) == '#')
        key = key.toLowerCase();
      if(this.channels.get(key)==null){
        this.createDiscussion(key);
      }
      StyledDocument discussion = (StyledDocument)this.channels.get(key);
      try{
        AttributeSet styles = null;
        styles = discussion.getStyle(style);
        discussion.insertString(discussion.getLength(),"\n", styles);
        StringTokenizer lxr = new StringTokenizer(message);
        while(lxr.hasMoreTokens()){
          discussion.insertString(discussion.getLength(),
                                  lxr.nextToken()+" ", discussion.getStyle(style));
        }
      }catch(Exception e){_logger.error("",e);}
      this.channels.put(key, discussion);
    }

    public ConnectionAntPanel getCaller(){
      return this.caller;
    }

    public ChatAntPanel getChatPanel(){
      return this.chatPanel;
    }

    public void refreshUsers(String channel){
      if(channel != null && channel.length() > 0 && channel.charAt(0) == '#')
        channel = channel.toLowerCase();
      User[] users = this.getUsers(channel);
      Arrays.sort(users, new UsersComparator());
      this.chatPanel.setUserList(users);
      //this.caller.setIrcUsersNumberInChannel(this.getUsers(channel).length, channel);
      this.chatPanel.updateUsersNumberInCurrentChannel(this.getUsers(channel).length);
      this.chatPanel.setChannel(channel);
    }

    public void onQuit(String sourceNick, String sourceLogin, String sourceHostname, String reason){
      String channel = this.chatPanel.getCurrentSelectedDiscussion();
      this.setControlMessage(channel, sourceNick + " " +ji.JI.i("quit irc at")+" "+(new Date()).toLocaleString());
      this.setControlMessage(IrcBot.connectionStateChannel, sourceNick + " " + ji.JI.i("quit irc at")+" "+(new Date()).toLocaleString());
      this.chatPanel.refreshCurrentChannel();
    }


    public void onNickChange(String oldNick, String login, String hostname, String newNick) {
      Object[] discussionsArray = this.getDiscussions();
      for (int x = 0; x < discussionsArray.length; x++) {
        String discussionName = (String) discussionsArray[x];
        if (discussionName.charAt(0) == '#') {
          Object[] usersTemp = this.getUsers(discussionName);
          Object[] users = new Object[usersTemp.length];
          for (int y = 0; y < usersTemp.length; y++) {
            users[y] = ( (User) usersTemp[y]).getNick();
          }
          if (Arrays.binarySearch(users, oldNick) >= 0 ||
              Arrays.binarySearch(users, newNick) >= 0) {
            this.setControlMessage(discussionName,
                                   oldNick + " " +ji.JI.i("is now known as")+ " " + newNick);
          }
        }
      }
      this.setControlMessage(IrcBot.connectionStateChannel, oldNick + " " + ji.JI.i("is now known as") + " " + newNick);
      this.chatPanel.refreshCurrentChannel();
      if(oldNick.equals(ConnectionAntPanel.nick))
        this.caller.setNick(newNick);
    }

    public void onOp(String channel, String sourceNick, String sourceLogin, String sourceHostname, String recipient){
      channel = channel.toLowerCase();
      this.setControlMessage(channel, recipient + " " + ji.JI.i("received @ from")+" "+sourceNick+" "+  ji.JI.i("on")+" "+channel+" "+ji.JI.i("at")+" "+(new Date()).toLocaleString());
      if(channel != null && channel.equals(this.chatPanel.getCurrentSelectedDiscussion())){
        //this.caller.setIrcUsersNumberInChannel(this.getUsers(channel).length, channel);
        this.chatPanel.updateUsersNumberInCurrentChannel(this.getUsers(channel).length);
        Object[] selected = this.chatPanel.getUserList().getSelectedValues();
        this.refreshUsers(channel);
        this.chatPanel.getUserList().setSelectionMode(ListSelectionModel.
            MULTIPLE_INTERVAL_SELECTION);
        int[] selectedIndices = new int[selected.length];
        for (int x = 0; x < selected.length; x++) {
          for (int y = 0; y < this.chatPanel.getUserList().getModel().getSize();
               y++) {
            if ( ( (User)this.chatPanel.getUserList().getModel().getElementAt(y)).
                getNick().equals( ( (User) selected[x]).getNick()))
              selectedIndices[x] = y;
          }
          this.chatPanel.getUserList().setSelectedIndices(selectedIndices);
        }
      }
      this.chatPanel.checkOp();
    }

    public void onDeop(String channel, String sourceNick, String sourceLogin, String sourceHostname, String recipient) {
      channel = channel.toLowerCase();
      this.setControlMessage(channel, ji.JI.i("You get de@ on")+" "+channel+" "+ji.JI.i("at")+" "+(new Date()).toLocaleString());
      if(channel != null && channel.equals(this.chatPanel.getCurrentSelectedDiscussion())){
        //this.caller.setIrcUsersNumberInChannel(this.getUsers(channel).length, channel);
        this.chatPanel.updateUsersNumberInCurrentChannel(this.getUsers(channel).length);
        Object[] selected = this.chatPanel.getUserList().getSelectedValues();
        this.refreshUsers(channel);
        this.chatPanel.getUserList().setSelectionMode(ListSelectionModel.
            MULTIPLE_INTERVAL_SELECTION);
        int[] selectedIndices = new int[selected.length];
        for (int x = 0; x < selected.length; x++) {
          for (int y = 0; y < this.chatPanel.getUserList().getModel().getSize();
               y++) {
            if ( ( (User)this.chatPanel.getUserList().getModel().getElementAt(y)).
                getNick().equals( ( (User) selected[x]).getNick()))
              selectedIndices[x] = y;
          }
          this.chatPanel.getUserList().setSelectedIndices(selectedIndices);
        }
      }
      this.chatPanel.checkOp();
    }

    public void onRemoveChannelBan(String channel, String sourceNick, String sourceLogin, String sourceHostname, String hostmask) {
      String selectedChannel = this.chatPanel.getCurrentSelectedDiscussion();
      this.setControlMessage(selectedChannel, hostmask + " " +ji.JI.i("unbanned from")+ " " + channel);
      this.chatPanel.refreshCurrentChannel();
      this.chatPanel.refreshBanList();
    }

    public void onSetChannelBan(String channel, String sourceNick, String sourceLogin, String sourceHostname, String hostmask) {
      String selectedChannel = this.chatPanel.getCurrentSelectedDiscussion();
      this.setControlMessage(selectedChannel, hostmask + " " + ji.JI.i("banned from") + " " + channel);
      this.chatPanel.refreshCurrentChannel();
      this.chatPanel.refreshBanList();
    }

    public void onKick(String channel, String kickerNick, String kickerLogin, String kickerHostname, String recipientNick, String reason) {
      channel = channel.toLowerCase();
      if(!recipientNick.equals(ConnectionAntPanel.nick)){
        this.setControlMessage(channel,
                               recipientNick + " " + ji.JI.i("has been kicked by") + " " + kickerNick +
                               " " + ji.JI.i("on") + " " + channel + " " +ji.JI.i("at") + " " +
                               (new Date()).toLocaleString() + " " +ji.JI.i("reason:") + " " +
                               reason);
        if (channel != null &&
            channel.equals(this.chatPanel.getCurrentSelectedDiscussion())) {
          //this.caller.setIrcUsersNumberInChannel(this.getUsers(channel).length, channel);
          this.chatPanel.updateUsersNumberInCurrentChannel(this.getUsers(channel).length);
          Object[] selected = this.chatPanel.getUserList().getSelectedValues();
          this.refreshUsers(channel);
          this.chatPanel.getUserList().setSelectionMode(ListSelectionModel.
              MULTIPLE_INTERVAL_SELECTION);
          int[] selectedIndices = new int[selected.length];
          for (int x = 0; x < selected.length; x++) {
            for (int y = 0; y < this.chatPanel.getUserList().getModel().getSize();
                 y++) {
              if ( ( (User)this.chatPanel.getUserList().getModel().getElementAt(y)).
                  getNick().equals( ( (User) selected[x]).getNick()))
                selectedIndices[x] = y;
            }
            this.chatPanel.getUserList().setSelectedIndices(selectedIndices);
          }
        }
      }
    }

    public void onVoice(String channel, String sourceNick, String sourceLogin, String sourceHostname, String recipient) {
      channel = channel.toLowerCase();
      this.setControlMessage(channel, ji.JI.i("You get voice on")+" "+channel+" "+ji.JI.i("at")+" "+(new Date()).toLocaleString());
      if(channel != null && channel.equals(this.chatPanel.getCurrentSelectedDiscussion())){
        //this.caller.setIrcUsersNumberInChannel(this.getUsers(channel).length, channel);
        this.chatPanel.updateUsersNumberInCurrentChannel(this.getUsers(channel).length);
        Object[] selected = this.chatPanel.getUserList().getSelectedValues();
        this.refreshUsers(channel);
        this.chatPanel.getUserList().setSelectionMode(ListSelectionModel.
            MULTIPLE_INTERVAL_SELECTION);
        int[] selectedIndices = new int[selected.length];
        for (int x = 0; x < selected.length; x++) {
          for (int y = 0; y < this.chatPanel.getUserList().getModel().getSize();
               y++) {
            if ( ( (User)this.chatPanel.getUserList().getModel().getElementAt(y)).
                getNick().equals( ( (User) selected[x]).getNick()))
              selectedIndices[x] = y;
          }
          this.chatPanel.getUserList().setSelectedIndices(selectedIndices);
        }
      }
    }

    public void onDeVoice(String channel, String sourceNick, String sourceLogin, String sourceHostname, String recipient) {
      channel = channel.toLowerCase();
      this.setControlMessage(channel, ji.JI.i("You get deVoice on")+" "+channel+" "+ji.JI.i("at")+" "+(new Date()).toLocaleString());
      if(channel != null && channel.equals(this.chatPanel.getCurrentSelectedDiscussion())){
        //this.caller.setIrcUsersNumberInChannel(this.getUsers(channel).length, channel);
        this.chatPanel.updateUsersNumberInCurrentChannel(this.getUsers(channel).length);
        Object[] selected = this.chatPanel.getUserList().getSelectedValues();
        this.refreshUsers(channel);
        this.chatPanel.getUserList().setSelectionMode(ListSelectionModel.
            MULTIPLE_INTERVAL_SELECTION);
        int[] selectedIndices = new int[selected.length];
        for (int x = 0; x < selected.length; x++) {
          for (int y = 0; y < this.chatPanel.getUserList().getModel().getSize();
               y++) {
            if ( ( (User)this.chatPanel.getUserList().getModel().getElementAt(y)).
                getNick().equals( ( (User) selected[x]).getNick()))
              selectedIndices[x] = y;
          }
          this.chatPanel.getUserList().setSelectedIndices(selectedIndices);
        }
      }
    }

    public void onJoin(String channel, String sender, String login, String hostname){
      channel = channel.toLowerCase();
      if(sender.equals(ConnectionAntPanel.nick)){
        this.setControlMessage(channel, ji.JI.i("You joined")+" "+channel+" "+ji.JI.i("at")+" "+(new Date()).toLocaleString());
        this.chatPanel.setChannel(channel);
      }else{
        this.setControlMessage(channel, sender + " " + ji.JI.i("joined")+" "+channel+" "+ji.JI.i("at")+" "+(new Date()).toLocaleString());
        this.chatPanel.refreshCurrentChannel();
      }
    }

    public void onPart(String channel, String sender, String login, String hostname){
      channel = channel.toLowerCase();
      if(!sender.equals(ConnectionAntPanel.nick)){
        this.setControlMessage(channel, sender + " " + ji.JI.i("parted")+" "+channel+" "+ji.JI.i("at")+" "+(new Date()).toLocaleString());
        if(channel != null && channel.equals(this.chatPanel.getCurrentSelectedDiscussion())){
          //this.caller.setIrcUsersNumberInChannel(this.getUsers(channel).length, channel);
          this.chatPanel.updateUsersNumberInCurrentChannel(this.getUsers(channel).length);
          Object[] selected = this.chatPanel.getUserList().getSelectedValues();
          this.refreshUsers(channel);
          this.chatPanel.getUserList().setSelectionMode(ListSelectionModel.
              MULTIPLE_INTERVAL_SELECTION);
          int[] selectedIndices = new int[selected.length];
          for (int x = 0; x < selected.length; x++) {
            for (int y = 0; y < this.chatPanel.getUserList().getModel().getSize();
                 y++) {
              if ( ( (User)this.chatPanel.getUserList().getModel().getElementAt(y)).
                  getNick().equals( ( (User) selected[x]).getNick()))
                selectedIndices[x] = y;
            }
            this.chatPanel.getUserList().setSelectedIndices(selectedIndices);
          }
        }
      }else{
        if(channel.equals(ConnectionAntPanel.ircChannel)){
          try{
            Thread.sleep(2000);
            this.joinChannel(ConnectionAntPanel.ircChannel);
            Thread.sleep(3000);
            this.refreshUsers(ConnectionAntPanel.ircChannel);
          }catch(Exception e){}
        }
      }
    }

    public String getActiveChannel(){
      return this.chatPanel.getCurrentSelectedDiscussion();
    }

    public void onConnect(){
      try{
        synchronized(this){
          //this.caller.setIrcUsersNumberInChannel(0, "");
          chatPanel = new ChatAntPanel(this);
          this.chatPanel.updateUsersNumberInCurrentChannel(0);
          this.caller.getContainer().getTabbedPane().add(chatPanel, new LabelIcon("IRC: " + this.getServer(),
              DoubleBuffer.getInstance().getButton(2), chatPanel));
        }
      }catch(Exception e){_logger.error("",e);}
      _logger.info("IRC Connected");
      this.caller.getContainer().getSettingsAntPanel().setIrcConnected(true);
      this.caller.getContainer().getSettingsAntPanel().setIrcEnabled(true);
    }

    public void onTopic(String channel, String topic, String setBy, long date, boolean changed){
      this.createTopic(channel, topic);
      this.setControlMessage(channel, setBy + " " + ji.JI.i("set topic:")+" \"" + topic + "\" "+ji.JI.i("at")+" "+(new Date(date)).toLocaleString());
      String selectedChannel = this.chatPanel.getCurrentSelectedDiscussion();
      if(channel.equals(selectedChannel)){
        this.chatPanel.setTopic(this.getTopic(channel));
      }
    }

    public void onServerResponse(int code, String response) {
      super.onServerResponse(code, response);

      response = response.substring(this.getNick().length() + 1);
      if(code == ReplyConstants.RPL_WHOISUSER ||
         code == ReplyConstants.RPL_WHOISSERVER ||
         code == ReplyConstants.RPL_WHOISCHANNELS ||
         code == ReplyConstants.RPL_ENDOFWHOIS){
        String selectedChannel = this.chatPanel.getCurrentSelectedDiscussion();
        if(this.banWhoisResult && code == ReplyConstants.RPL_WHOISUSER){
          response = response.substring(response.indexOf(' ') + 1);
          response = response.substring(response.indexOf(' ') + 1);
          response = response.substring(0, response.indexOf('*'));
          this.ban(this.banFromChannel, "*!*@"+response);
          this.banFromChannel = null;
          this.banWhoisResult = false;
        }else
          this.setControlMessage(selectedChannel, response);
      }else if(code > 0 && code < 3 ||
               code == ReplyConstants.RPL_MOTDSTART ||
               code == ReplyConstants.RPL_MOTD ||
               code >= 251 && code <= 266){
        try{
          this.setControlMessage(IrcBot.connectionStateChannel, response);
        }catch(Exception e){}
      }else if(code == ReplyConstants.RPL_BANLIST){
        String selectedChannel = this.chatPanel.getCurrentSelectedDiscussion();
        if(response.startsWith(selectedChannel+" ")){
          response = response.substring((selectedChannel+" ").length());
          response = response.substring(0, response.indexOf(' '));
          this.chatPanel.addBanlistElement(response);
        }
      }else if(code == ReplyConstants.RPL_LIST){
        try{
          this.channelCounter++;
          String name = response.substring(0,response.indexOf(' '));
          response = response.substring(response.indexOf(' '));
          String users = response.substring(0,response.indexOf(':'));
          response = response.substring(response.indexOf(':'));
          this.setStyledControlMessage(IrcBot.connectionStateChannel, name,
                                       "blue");
          this.setStyledControlMessage(IrcBot.connectionStateChannel, ji.JI.i("Active users")+": " + users,
                                       "red");
          this.setStyledControlMessage(IrcBot.connectionStateChannel, response,
                                       "green");
        }catch(Exception e){}
      }else if(code == ReplyConstants.RPL_LISTSTART){
        this.channelCounter = 0;
        this.setStyledControlMessage(IrcBot.connectionStateChannel, ji.JI.i("Channels List"), "gray");
      }else if(code == ReplyConstants.RPL_LISTEND){
        this.setStyledControlMessage(IrcBot.connectionStateChannel, ji.JI.i("end of list")+": "+this.channelCounter+ji.JI.i(" channels listed"), "gray");
      }
    }

    public void scheduleBan(String nick, String channel){
      this.banWhoisResult = true;
      this.banFromChannel = channel;
      this.sendRawLine("WHOIS " + nick);
    }

    public void autoReconnect() {
      boolean stopTryingConnection = false;
      while (!stopTryingConnection && this.caller.autoReconnectIRC == true &&
             !this.inibitAutoreconnect &&
             !this.isConnected() && this.caller.warriorAnt != null &&
             !this.caller.warriorAnt.isDisconnected()) {
        try {
          Thread.currentThread().sleep(30000);
        }
        catch (Exception e) {}
        synchronized (this) {
          try {
            /* IrcBot Setup*/
            _logger.info("Trying to reconnect to IRC server");
            if (!ConnectionAntPanel.ircServer.equals("")) {
              String password = this.caller.getContainer().getSettingsAntPanel().
                  getIrcPassword();
              if (!password.equals(""))
                this.caller.ircBot.connect(ConnectionAntPanel.ircServer, 6667,
                                           password);
              else
                this.caller.ircBot.connect(ConnectionAntPanel.ircServer);
              Thread.sleep(2000);
              this.caller.ircBot.joinChannel(ConnectionAntPanel.ircChannel);
              Thread.sleep(2000);
              this.caller.ircBot.refreshUsers(ConnectionAntPanel.ircChannel);
            }
            /*Fine IrcBot setup*/
            this.caller.getContainer().getSettingsAntPanel().setIrcConnected(true);
            stopTryingConnection = true;
          }
          catch (Exception ex) {
            _logger.error("Failed to reconnect to IRC: " + ex.getMessage());
            if(!this.isConnected()){
              this.caller.getContainer().getSettingsAntPanel().setIrcConnected(false);
              this.caller.getContainer().getSettingsAntPanel().setIrcEnabled(false);
            }
          }
        }
        try {
          Thread.currentThread().sleep(30000);
        }
        catch (Exception e) {}
      }
      if(this.inibitAutoreconnect){
        try {
          this.dispose();
        }
        catch (Exception e) {}
      }
    }

    public void onDisconnect(){
      synchronized(this){
        _logger.info("IRC Disconnected");
        this.caller.getContainer().getSettingsAntPanel().setIrcConnected(false);
        this.caller.getContainer().getSettingsAntPanel().setIrcEnabled(false);
      }
      this.autoReconnect();
    }

    public void onAction(String sender, String login, String hostname, String target, String action) {
      this.setControlMessage(target, "* "+sender+" "+action);
    }

    public void onANtsCommandMessage(String sender, String login, String hostname,
                                     String message) {
      if (message == null || !ConnectionAntPanel.searchPeersOnIRC)
        return;
      else if (message.equalsIgnoreCase("ANtsCommandCode:0000")) {
        _logger.info("Received connect message from: " + sender + " " +
                     login + " " + hostname);
        try {
          this.sendCTCPCommand(sender,
                      "ANtsResponseCode:0000 " +
                      caller.getLocalStringAddress() +
                      ":" + (caller.warriorAnt.getServerPort()));
        }
        catch (Exception e) {
          _logger.error("", e);
        }
      }
      else if (message.equalsIgnoreCase("ANtsCommandCode:0003")) {
        _logger.info("Received connect message from: " + sender + " " +
                     login + " " + hostname);
        try {
          this.sendCTCPCommand(sender,
                      "ANtsResponseCode:0003 " +
                      caller.getLocalStringAddress() +
                      ":" + (caller.warriorAnt.getServerPort()));
        }
        catch (Exception e) {
          _logger.error("", e);
        }
      }
      else if (message.indexOf("ANtsCommandCode:0004 ") >= 0) {
        _logger.info("Received firewall probe message from: " +
                     sender + " " + login + " " + hostname);
        int beginIndex = message.indexOf("ANtsCommandCode:0004 ");
        beginIndex += "ANtsCommandCode:0004 ".length();
        message = message.substring(beginIndex, message.length());
        int endIndex = message.indexOf(":");
        try {
          if (! (InetAddress.getByName(message.substring(0, endIndex)).
                 getHostAddress().equals(InetAddress.getLocalHost().
                                         getHostAddress()) &&
                 message.substring(endIndex + 1,
                                   message.length()).equals(caller.warriorAnt.
              getServerPort() +
              ""))) {
            _logger.info("Probing firewall of: "+message.substring(0, endIndex)+":"+
                         Integer.parseInt(message.substring(endIndex + 1, message.length())));
            Socket probeSocket = ants.p2p.security.sockets.SSLProvider.getSSLSecuredSocket(
                message.substring(0, endIndex),
                Integer.parseInt(message.substring(endIndex + 1, message.length())),
                ants.p2p.Ant.proxied);
            ObjectOutputStream probeOutputStream = new ObjectOutputStream(probeSocket.getOutputStream());
            probeOutputStream.write(0);
            probeOutputStream.close();
            _logger.info("Probe firewall: Firewall DOWN");
            this.sendCTCPCommand(sender, "ANtsResponseCode:0004 FWDW");
          }
        }
        catch (Exception e) {
          _logger.info("Probe firewall: Firewall UP["+e.getMessage()+"]");
          this.sendCTCPCommand(sender,
                      "ANtsResponseCode:0004 FWUP");
        }
      }
      else if (message.indexOf("ANtsResponseCode:0004 ") >= 0) {
        int beginIndex = message.indexOf("ANtsResponseCode:0004 ");
        beginIndex += "ANtsResponseCode:0004 ".length();
        message = message.substring(beginIndex, message.length());
        if(message.equals("FWUP")){
          _logger.info("Probe firewall: Your Firewall is UP!");
          this.caller.setFirewallState(true);
        }else if(message.equals("FWDW")){
          _logger.info("Probe firewall: Your Firewall is DOWN!");
          this.caller.setFirewallState(false);
        }
      }
      else if (message.indexOf("ANtsCommandCode:0001 ") >= 0) {
        _logger.info("Received request connection message from: " +
                     sender + " " + login + " " + hostname);
        int beginIndex = message.indexOf("ANtsCommandCode:0001 ");
        beginIndex += "ANtsCommandCode:0001 ".length();
        message = message.substring(beginIndex, message.length());
        int endIndex = message.indexOf(":");
        try {
          _logger.info("Trying connection...");
          if (! (InetAddress.getByName(message.substring(0, endIndex)).
                 getHostAddress().equals(InetAddress.getLocalHost().
                                         getHostAddress()) &&
                 message.substring(endIndex + 1,
                                   message.length()).equals(caller.warriorAnt.
              getServerPort() +
              ""))) {
            caller.warriorAnt.addP2PNeighbour(message.substring(0, endIndex),
                                           Integer.parseInt(message.substring(
                                           endIndex + 1, message.length())),
                                           true, FrameAnt.
                                           getInstance(null).getGuiAnt().
                                           getConnectionAntPanel().
                                           getLocalInetAddress());
          }
        }
        catch (Exception e) {
          _logger.error("", e);
        }
      }
      else if (message.indexOf("ANtsCommandCode:0002 ") >= 0) {
        _logger.info("Received op request message from: " + sender + " " +
                     login + " " + hostname);
        int beginIndex = message.indexOf("ANtsCommandCode:0002 ");
        beginIndex += "ANtsCommandCode:0002 ".length();
        message = message.substring(beginIndex, message.length());
        int endIndex = message.indexOf(" ");
        String passwd = message.substring(0, endIndex);
        String channel = message.substring(endIndex + 1, message.length());
        if (!WarriorAnt.password.equals("") &&
            WarriorAnt.password.equals(passwd)) {
          this.op(channel, sender);
        }
      }
      else if (message.indexOf("ANtsResponseCode:0000 ") >= 0) {
        _logger.info("Received peer address message from: " + sender +
                     " " + login + " " + hostname);
        int beginIndex = message.indexOf("ANtsResponseCode:0000 ");
        beginIndex += "ANtsResponseCode:0000 ".length();
        message = message.substring(beginIndex, message.length());
        int endIndex = message.indexOf(":");
        try {
          _logger.info("Setting routing point...");
          if (! (InetAddress.getByName(message.substring(0, endIndex)).
                 getHostAddress().equals(InetAddress.getLocalHost().
                                         getHostAddress()) &&
                 message.substring(endIndex + 1,
                                   message.length()).equals( (caller.warriorAnt.
              getServerPort() +
              1) + ""))) {
            this.caller.setRoutingPoint(InetAddress.getByName(message.substring(
                0, endIndex)),
                                        Integer.parseInt(message.substring(
                endIndex + 1, message.length())));
          }
        }
        catch (Exception e) {
          _logger.error("", e);
        }
      }
      else if (message.indexOf("ANtsResponseCode:0003 ") >= 0) {
        _logger.info("Received peer address message from: " + sender +
                     " " + login + " " + hostname);
        int beginIndex = message.indexOf("ANtsResponseCode:0003 ");
        beginIndex += "ANtsResponseCode:0003 ".length();
        message = message.substring(beginIndex, message.length());
        int endIndex = message.indexOf(":");
        try {
          _logger.info("Setting routing point...");
          if (! (InetAddress.getByName(message.substring(0, endIndex)).
                 getHostAddress().equals(InetAddress.getLocalHost().
                                         getHostAddress()) &&
                 message.substring(endIndex + 1,
                                   message.length()).equals( (caller.warriorAnt.
              getServerPort() +
              1) + ""))) {
            this.caller.setRoutingPoint(InetAddress.getByName(message.substring(
                0, endIndex)),
                                        Integer.parseInt(message.substring(
                endIndex + 1, message.length())));
            RefreshAndConnectThread refreshAndConnectThread = new
                RefreshAndConnectThread(this.caller);
            refreshAndConnectThread.start();
            refreshAndConnectThread.join();
          }
        }
        catch (Exception e) {
          _logger.error("", e);
        }
      }
    }

    public void onPrivateMessage(String sender, String login, String hostname, String message){
      if (message == null){
        return;
      }
      else {
        this.chatPanel.setMessage(sender, sender, message);
      }
    }

    public void onMessage(String channel, String sender, String login,
                          String hostname, String message) {
      if (channel != null && sender != null && message != null) {
        channel = channel.toLowerCase();
        this.chatPanel.setMessage(channel, sender, message);
      }
    }
    /*
    public static void main(String args[]){
      try{
        // Now start our bot up.
        IrcBot bot = new IrcBot(null);

        // Enable debugging output.
        bot.setVerbose(true);
        bot.startIdentServer();

        // Connect to the IRC server.
        bot.connect("irc.azzurra.org");

        // Join the #pircbot channel.
        bot.joinChannel("#ants-dev");
      }catch(Exception e){
        _logger.error("",e);
      }
    }*/
}
